package cn.tedu.springboot01.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect // @Aspect注解标识被标注的类为切面类
@Component
public class AspectDemo {

    /**
     * @Pointcut注解用来统一去管理切入点 使用@Pointcut和任意方法结合使用就可以让通知注解中绑定的切入点表达式为一个方法名即可
     */
    // @Pointcut("bean(userServiceImpl) || bean(awardServiceImpl)")
    // @Pointcut("execution(* cn.tedu.springboot01.service.*.*(..))")
    // @Pointcut("execution(* cn..service.*.*(..))")
    // @Pointcut("execution(* *Service.find*(..))")
    // @Pointcut("execution(* *Service.*(..))")
    @Pointcut("execution(* cn.tedu.springboot01.service.UserService.login(String,String)) ||" +
            "execution(* cn.tedu.springboot01.service.AwardService.grantAward(..))")
    public void userService() {
    }

    // @Before是前置通知，在目标方法执行之前通知执行切面中扩展的业务代码
    @Before("userService()")
    public void test01(JoinPoint joinPoint) {
        // JoinPoint:连接点，就是aop进行插入的位置
        Signature signature = joinPoint.getSignature();
        System.out.println(signature.getName() + "方法执行之前去执行的");
    }

    // @After是后置通知，在目标方法执行之前通知执行切面中扩展的业务代码
    @After("userService()")
    public void test02(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        System.out.println(signature.getName() + "方法执行之后去执行的");
    }

    //  @AfterReturning通知是在业务代码正常执行之后执行的扩展业务代码
    @AfterReturning(value = "userService()", returning = "result")
    public void test03(JoinPoint joinPoint, Object result) {
        Signature signature = joinPoint.getSignature();
        System.out.println("在" + signature.getName() + "方法正常执行之后去执行的,方法返回的值为" + result);
    }

    // @AfterReturning通知是在业务代码执行出现异常之后执行的扩展业务代码
    @AfterThrowing(value = "userService()", throwing = "e")
    public void test04(JoinPoint joinPoint, Exception e) {
        Signature signature = joinPoint.getSignature();
        System.out.println("在" + signature.getName() + "方法出现异常之后去执行的，异常信息为：" + e);
    }

}
